package repository

import (
	"awesomeProject/internal/model"
	"awesomeProject/pkg/errors"
	"context"

	"gorm.io/gorm"
)

type CategoryRepository interface {
	Create(ctx context.Context, category *model.Category) error
	GetByID(ctx context.Context, id uint) (*model.Category, error)
	GetByName(ctx context.Context, name string) (*model.Category, error)
	Update(ctx context.Context, category *model.Category) error
	Delete(ctx context.Context, id uint) error
	List(ctx context.Context) ([]*model.Category, error)
	GetAll(ctx context.Context) ([]*model.Category, error)
	GetPostCount(ctx context.Context, categoryID uint) (int64, error)
}

type categoryRepository struct {
	db *gorm.DB
}

// NewCategoryRepository 创建分类仓库实例
func NewCategoryRepository(db *gorm.DB) CategoryRepository {
	return &categoryRepository{db: db}
}

// Create 创建分类
func (r *categoryRepository) Create(ctx context.Context, category *model.Category) error {
	return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
		// 检查分类名是否已存在
		var existingCategory model.Category
		if err := tx.Where("name = ?", category.Name).First(&existingCategory).Error; err == nil {
			return errors.ErrCategoryExists
		}
		return tx.Create(category).Error
	})
}

// GetByID 根据id查询分类
func (r *categoryRepository) GetByID(ctx context.Context, id uint) (*model.Category, error) {
	var category model.Category
	result := r.db.WithContext(ctx).First(&category, id)
	if result.Error != nil {
		return nil, result.Error
	}
	return &category, nil
}

// GetByName 根据名称查询分类
func (r *categoryRepository) GetByName(ctx context.Context, name string) (*model.Category, error) {
	var category model.Category
	result := r.db.WithContext(ctx).Where("name = ?", name).First(&category)
	if result.Error != nil {
		return nil, result.Error
	}
	return &category, nil
}

// Update 更新分类
func (r *categoryRepository) Update(ctx context.Context, category *model.Category) error {
	return r.db.WithContext(ctx).Save(category).Error
}

// Delete 删除分类
func (r *categoryRepository) Delete(ctx context.Context, id uint) error {
	return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
		// 检查是否有帖子使用此分类
		var count int64
		if err := tx.Model(&model.Post{}).Where("category_id = ?", id).Count(&count).Error; err != nil {
			return err
		}
		if count > 0 {
			return errors.ErrCategoryHasPosts
		}
		return tx.Delete(&model.Category{}, id).Error
	})
}

// List 查询所有分类
func (r *categoryRepository) List(ctx context.Context) ([]*model.Category, error) {
	var categories []*model.Category
	result := r.db.WithContext(ctx).Order("created_at DESC").Find(&categories)
	if result.Error != nil {
		return nil, result.Error
	}
	return categories, nil
}

// GetAll 获取所有分类（与List方法相同，为了兼容性）
func (r *categoryRepository) GetAll(ctx context.Context) ([]*model.Category, error) {
	return r.List(ctx)
}

// GetPostCount 获取分类下的帖子数量
func (r *categoryRepository) GetPostCount(ctx context.Context, categoryID uint) (int64, error) {
	var count int64
	err := r.db.WithContext(ctx).Model(&model.Post{}).Where("category_id = ?", categoryID).Count(&count).Error
	return count, err
}
